/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package blueprint4j.gui.db;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JPanel;

import blueprint4j.Constants;
import blueprint4j.db.DataException;
import blueprint4j.db.Entity;
import blueprint4j.db.Field;
import blueprint4j.db.FieldCombiner;
import blueprint4j.db.FieldForeignKey;
import blueprint4j.gui.Gui;
import blueprint4j.gui.JThinLabel;
import blueprint4j.utils.Log;
import blueprint4j.utils.VectorString;

/**
 * This is a default class for field list binders takes the field returns
 * its name as the column name and the width as specififed. Returns the column value
 * in a jLabel.
 */
public class DefaultFieldBinder implements EntityPanelFieldBinder {
    private int width;
    private String field_name;
    private Entity foreign= null;
    private Field foreign_bind = null;
    //private int field_pos=0;
    private VectorString fieldnames = new VectorString();
    private VectorString allfields = new VectorString();
    
    public DefaultFieldBinder(Field field,int width) {
        for (int i  = 0;i < field.getEntity().getFields().size();i++) {
            allfields.add(field.getEntity().getFields().get(i).getName());
        }
        if (field instanceof FieldCombiner) {
            for (int i = 0;i < ((FieldCombiner)field).getFields().length;i++) {
                fieldnames.add(((FieldCombiner)field).getFields()[i].getName());
            }
        } else {
            fieldnames = new VectorString(new String[]{field.getName()});
        }
        field_name=field.getDescription();
        this.width = width;
    }
    
    public DefaultFieldBinder(Field field,int width,Entity foreign,Field foreign_bind) {
        this(field,width);
        this.foreign = foreign;
        this.foreign_bind = foreign_bind;
    }
    
    public String getColumnName() {
        return field_name;
    }
    
    public int getColumnWidth() {
        return width;
    }
    
    public JComponent getFieldComponent(Entity entity) {
        try {
            if (foreign != null) {
                try {
                    Entity referenced = entity.getAffiliatedEntity(foreign,foreign_bind);
                    if (referenced ==null) {
                        throw new DataException(
                                "Database integrity lost. Entity ["+entity.getTableName()+"] "+
                                "reference ["+foreign.getTableName()+"] on ["+foreign_bind.getObject()+"] was not found"
                                );
                    }
                    entity = referenced;
                } catch (Exception exception) {
                    exception.printStackTrace();
                    Log.debug.out(exception);
                }
            }
            JThinLabel label=new JThinLabel();
            Field field[] = new Field[fieldnames.size()];
            for (int i = 0;i < fieldnames.size();i++) {
                field[i] = entity.getFields().get(allfields.indexOf(fieldnames.get(i)));
            }
            // IF THE FIELD IS A FOREIGN FIELD THENLOAD AS A COMBINER
            if (field.length == 1 && field[0] instanceof FieldForeignKey) {
                Entity tmpentity = ((FieldForeignKey)field[0]).retrieve();
                if (tmpentity!=null){
                	field = tmpentity.getFields().getNameField().toArray();
                }else{
                	field=new Field[0];
                }
            }
            if (field.length == 1) {
                if (field[0] instanceof blueprint4j.db.FieldColor) {
                    Color c = ((blueprint4j.db.FieldColor)field[0]).get();
                    if (c==null) {
                        c=Color.GRAY;
                    }
                    label.setBackground(c);
                    label.setBorder(BorderFactory.createEtchedBorder());
                    label.setOpaque(true);
                } else if (field[0] instanceof blueprint4j.db.FieldImageResource) {
                    try {
                        if (((blueprint4j.db.FieldImageResource)field[0]).get() != null) {
                            return new JThinLabel(Gui.loadIconsFromResource(new String[]{((blueprint4j.db.FieldImageResource)field[0]).get()})[0]);
                        } else {
                            return new JThinLabel();
                        }
                    } catch (Exception exception) {
                        exception.printStackTrace();
                        Log.critical.out(exception);
                    }
                } else if (field[0] instanceof blueprint4j.db.FieldBoolean) {
                    try {
                        JPanel panel=new JPanel(new FlowLayout(FlowLayout.CENTER,0,0));
                        JCheckBox box=new JCheckBox();
                        box.setMargin(new Insets(0,0,0,0));
                        //panel.add(box);
                        if (
                                ((blueprint4j.db.FieldBoolean)field[0]).get() == null
                                ) {
                            // Do nothing
                        } else if (
                                !((blueprint4j.db.FieldBoolean)field[0]).get().booleanValue()
                                ) {
                            panel.add(box);
                            box.setSelected(false);
                        } else {
                            panel.add(box);
                            box.setSelected(true);
                        }
                        box.setOpaque(false);
                        panel.setOpaque(false);
                        return panel;
                    } catch (Exception exception) {
                        exception.printStackTrace();
                        Log.critical.out(exception);
                    }
                } else {
                    label.setText(field[0].toString());
                }
            } else {
                String text = "";
                // must be a field combiner
                for (int i =0;i < field.length;i++) {
                    text += field[i].toString() + " ";
                }
                if (text.length() > 0) {
                    text = text.substring(0,text.length()-1);
                }
                label.setText(text);
            }
            return label;
        } catch (DataException de) {
            Log.debug.out(de);
        }
        return null;
    }
    
    public Field getField() {return foreign_bind;}
}

